package cn.xetsoft.supermarket.service.impl;

import cn.xetsoft.supermarket.common.DataResponse;
import cn.xetsoft.supermarket.dao.OrderItemDao;
import cn.xetsoft.supermarket.entity.Cart;
import cn.xetsoft.supermarket.entity.Good;
import cn.xetsoft.supermarket.entity.Order;
import cn.xetsoft.supermarket.dao.OrderDao;
import cn.xetsoft.supermarket.entity.OrderItem;
import cn.xetsoft.supermarket.service.Bean;
import cn.xetsoft.supermarket.service.GoodService;
import cn.xetsoft.supermarket.service.OrderItemService;
import cn.xetsoft.supermarket.service.OrderService;
import cn.xetsoft.supermarket.util.BigDecimalUtil;
import cn.xetsoft.supermarket.util.OrderNoUtils;
import cn.xetsoft.supermarket.util.RegexUtils;
import cn.xetsoft.supermarket.vo.OrderVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author 侯国强
 * @since 2020/12/20 21:11:47
 * @version 1.0
 * @Description (Order)表服务实现类
 */

@Slf4j //使用lombok日志的注解
public class OrderServiceImpl implements OrderService {

    //订单dao
    private OrderDao orderDao;
    private OrderItemService orderItemService;

    //商品服务
    private GoodService goodService = Bean.getGoodServiceInstance();

    public OrderServiceImpl(OrderDao orderDao, OrderItemService orderItemService) {
        this.orderDao = orderDao;
        this.orderItemService = orderItemService;
    }

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public DataResponse<Order> queryById(Integer id) {
        //健壮性判断
        if (null == id){
            //日志警告提示
            log.warn("ID不能为空");
            return DataResponse.error("ID不能为空");
        }
        try {
            Order order = this.orderDao.queryById(id);
            if (null == order){
                //日志警告提示
                log.warn("查询订单列表");
                return DataResponse.error("查询订单列表");
            }
            return DataResponse.success(order);
        } catch (SQLException throwables) {
            //日志警告提示
            log.warn("异常 -> {}",throwables.getMessage());
            return DataResponse.errorException(throwables.getMessage());
        }
    }

    /**
     * 通过订单号查询单条数据
     *
     * @param orderNo 订单号
     * @return 实例对象
     */
    @Override
    public DataResponse<Order> queryByOrderNo(String orderNo) {
        //健壮性判断
        if (null == orderNo){
            //日志警告提示
            log.warn("订单号不能为空");
            return DataResponse.error("订单号不能为空");
        }
        try {
            Order order = this.orderDao.queryByorderNo(orderNo);
            if (null == order){
                //日志警告提示
                log.warn("查找订单不存在");
                return DataResponse.error("查找订单不存在");
            }
            return DataResponse.success(order);
        } catch (SQLException throwables) {
            //日志警告提示
            log.warn("异常 -> {}",throwables.getMessage());
            return DataResponse.errorException(throwables.getMessage());
        }
    }

    /**
     * 通过订单号模糊查询多条数据
     *
     * @param orderNo 订单号
     * @return 实例对象
     */
    @Override
    public DataResponse<List<Order>> queryByOrderNoLike(String orderNo) {
        //健壮性判断
        if (null == orderNo){
            //日志警告提示
            log.warn("订单号不能为空");
            return DataResponse.error("订单号不能为空");
        }
        try {
            List<Order> orders = this.orderDao.queryByOrderNoLike(orderNo);
            if (null == orders || orders.size() == 0){
                //日志警告提示
                log.warn("查找订单不存在");
                return DataResponse.error("查找订单不存在");
            }
            return DataResponse.success(orders);
        } catch (SQLException throwables) {
            //日志警告提示
            log.warn("异常 -> {}",throwables.getMessage());
            return DataResponse.errorException(throwables.getMessage());
        }
    }

    /**
     * 通过订单号查询单条数据
     *
     * @param date 时间
     * @return 实例对象
     */
    @Override
    public DataResponse<OrderVo> queryByDate(String date) {
        //健壮性判断
        if (null == date){
            //日志警告提示
            log.warn("订单号不能为空");
            return DataResponse.error("订单号不能为空");
        }
        //匹配是否是日期
        Date isDate = RegexUtils.parseDate(date);
        //格式化时间
        date = DateFormatUtils.format(isDate, "yyyy-MM-dd");

        try {
            List<Order> orders = this.orderDao.queryByDate(date);
            if (orders.size() == 0){
                //日志警告提示
                log.warn("订单列表空");
                return DataResponse.error("订单列表空");
            }
            /**
             * 组合显示数据
             * 把订单列表交给ordervo构造函数计算
             */
            OrderVo orderVo = new OrderVo(orders);

            return DataResponse.success(orderVo);
        } catch (SQLException throwables) {
            //日志警告提示
            log.warn("异常 -> {}",throwables.getMessage());
            return DataResponse.errorException(throwables.getMessage());
        }
    }

    /**
     * 通过订单号查询单条数据
     * @return 实例对象
     */
    @Override
    public DataResponse<OrderVo> queryByToday() {
        //格式化今天时间
        String date = DateFormatUtils.format(new Date(), "yyyy-MM-dd");

        try {
            List<Order> orders = this.orderDao.queryByDate(date);
            if (orders.size() == 0){
                //日志警告提示
                log.warn("订单列表空");
                return DataResponse.error("订单列表空");
            }
            /**
             * 组合显示数据
             * 把订单列表交给ordervo构造函数计算
             */
            OrderVo orderVo = new OrderVo(orders);

            return DataResponse.success(orderVo);
        } catch (SQLException throwables) {
            //日志警告提示
            log.warn("异常 -> {}",throwables.getMessage());
            return DataResponse.errorException(throwables.getMessage());
        }
    }

    /**
     * 通过订单号查询单条数据
     *
     * @return 实例对象
     */
    @Override
    public DataResponse<OrderVo> queryByNowMonth() {
        //格式化今天时间
        String date = DateFormatUtils.format(new Date(), "yyyy-MM");

        try {
            List<Order> orders = this.orderDao.queryByDate(date);
            if (orders.size() == 0){
                //日志警告提示
                log.warn("订单列表空");
                return DataResponse.error("订单列表空");
            }
            /**
             * 组合显示数据
             * 把订单列表交给ordervo构造函数计算
             */
            OrderVo orderVo = new OrderVo(orders);

            return DataResponse.success(orderVo);
        } catch (SQLException throwables) {
            //日志警告提示
            log.warn("异常 -> {}",throwables.getMessage());
            return DataResponse.errorException(throwables.getMessage());
        }
    }

    /**
     * 查询所有
     * @return 实例对象
     */
    @Override
    public DataResponse<OrderVo> queryAll() {
        try {
            List<Order> orders = this.orderDao.queryAll();
            if (orders.size() == 0){
                //日志警告提示
                log.warn("订单列表空");
                return DataResponse.error("订单列表空");
            }
            /**
             * 组合显示数据
             * 把订单列表交给ordervo构造函数计算
             */
            OrderVo orderVo = new OrderVo(orders);

            return DataResponse.success(orderVo);
        } catch (SQLException throwables) {
            //日志警告提示
            log.warn("异常 -> {}",throwables.getMessage());
            return DataResponse.errorException(throwables.getMessage());
        }
    }

    /**
     * 新增数据
     *
     * @param carts 购物车对象
     * @return 实例对象
     */
    @Override
    public DataResponse<OrderVo> insert(List<Cart> carts) {
        //健壮性判断
        if (null == carts || carts.size() == 0){
            //日志警告提示
            log.warn("创建订单购物车商品不能为空");
            return DataResponse.error("创建订单购物车商品不能为空");
        }
        //创建订单数据库
        Order order = new Order();

        //购物车信息校验
        DataResponse<OrderVo> response = ckeckCartData(carts);
        if (response != null) {
            //日志警告提示
            log.warn("校验失败 -> {}",response.getMsg());
            return response;
        }
        /**
         * 功能实现
         */
        try {
            //设置标签
            boolean flag = false;
            //订单号
            String orderNo = null;
            do {
                //生成订单号
                orderNo = OrderNoUtils.nextNo();
                //查找订单号
                flag = this.orderDao.checkOrderNo(orderNo);
                //如果存在重新生成
            } while (flag);

            //设置订单号
            order.setOrderNo(orderNo);

            /**
             * 1.将购物车商品转换成订单商品记录并加入数据库
             * 2.计算销售总价和进价总价
             * 3.获取简略信息
             */
            DataResponse orderItem = createOrderItem(carts, order);

            //判断是否操作成功
            if (!orderItem.isSuccess()){
                return orderItem;
            }
            //取其中一个商品作为经办人，因为其经办人一样
            order.setAgent(carts.get(0).getAgent());
            //订单和订单商品插入数据库
            this.orderDao.insert(order);
        } catch (SQLException throwables) {
            //日志警告提示
            log.warn("异常 -> {}",throwables.getMessage());
            return DataResponse.errorException(throwables.getMessage());
        }
        return this.queryAll();
    }


    /**
     * 1.将购物车商品转换成订单商品记录并加入数据库
     * 2.计算销售总价和进价总价
     * 3.获取简略信息
     *
     * @param carts 购物车列表
     * @param order 订单
     * @return 状态结果
     */
    private DataResponse createOrderItem(List<Cart> carts,Order order){

        /**
         * 定义计算总价，进价总价（用来计算利润）
         */
        //计算销售总价
        BigDecimal totalSalePrice = new BigDecimal(0.0);
        //计算进货总价 来计算订单利润
        BigDecimal totalInPrice = new BigDecimal(0.0);
        //记录商品订单简略详情
        StringBuilder desc =  new StringBuilder();

        //遍历转换及记录加入数据库
        for (Cart cart:carts){
            //售价和数量计算购物车售价统计
            BigDecimal cartSalePrice =BigDecimalUtil.mul(cart.getSaleprice().doubleValue(),cart.getQuantity().doubleValue());
            //计算销售总价
            totalSalePrice = BigDecimalUtil.add(totalSalePrice.doubleValue(),cartSalePrice.doubleValue());
            //进价与数量计算购物车进价统计
            BigDecimal cartInPrice = BigDecimalUtil.mul(cart.getInprice().doubleValue() , cart.getQuantity().doubleValue());
            //计算进货总价 来计算订单利润
            totalInPrice = BigDecimalUtil.add(totalInPrice.doubleValue(),cartInPrice.doubleValue());

            //提取简略详情
            //最大5个字符
            int len =cart.getGoodname().length();
            if (len >5) { //如果大于五个字符取五个字符
                desc.append(cart.getGoodname().substring(0, 5)).append("...");
            } else { //否则直接添加即可
                desc.append(cart.getGoodname()).append("...");
            }
            /**
             * 创建订单商品
             */
            OrderItem orderItem = new OrderItem();
            //设置订单
            orderItem.setOrderNo(order.getOrderNo());
            //设置数量
            orderItem.setQuantity(cart.getQuantity());
            //设置订单商品名称
            orderItem.setGoodname(cart.getGoodname());
            //设置商品品牌
            orderItem.setGoodbrand(cart.getGoodbrand());
            //设置售价
            orderItem.setSalePrice(cart.getSaleprice());
            //设置计价单位
            orderItem.setType(cart.getType());
            /**
             * 加入数据库
             */
            DataResponse<OrderItem> insert = orderItemService.insert(orderItem);
            if (!insert.isSuccess()){
                //日志警告提示
                log.warn("添加订单商品失败");
                return DataResponse.error("添加订单商品错误");
            }
            /**
             * 更新库存
             */
            //1.查询商品 名字是唯一的查询名字
            DataResponse<Good> goodDataResponse = goodService.queryByGoodname(cart.getGoodname());
            //判断状态，不成功返回结果
            if (!goodDataResponse.isSuccess()){
                log.warn("商品不存在");
                return DataResponse.error(goodDataResponse.getMsg());
            }
            //2.更新库存
            Good good = goodDataResponse.getData();
            good.setStock(good.getStock() - cart.getQuantity());
            //写入数据库
            DataResponse<Good> update = goodService.update(good);
            //如果不成功
            if (!update.isSuccess()){
                return update;
            }
        }
        //设置简略详情
        order.setDesc(desc.toString());
        //设置总价
        order.setTotalPrice(totalSalePrice);
        //设置订单利润
        order.setProfit(BigDecimalUtil.sub(totalSalePrice.doubleValue(), totalInPrice.doubleValue()));
        return DataResponse.success("订单商品加入成功");
    }

    /**
     * 新增数据
     * 初始化使用，其他不建议使用
     * @param order 订单
     * @return 实例对象
     */
    @Override
    public DataResponse<OrderVo> insert(Order order) {
        try {
            //查找订单号
            boolean flag = this.orderDao.checkOrderNo(order.getOrderNo());
            if (flag){
                //日志警告提示
                log.warn("订单号已存在");
                return DataResponse.error("订单号已存在");
            }

            //订单和订单商品插入数据库
            this.orderDao.insert(order);
        } catch (SQLException throwables) {
            //日志警告提示
            log.warn("异常 -> {}",throwables.getMessage());
            return DataResponse.errorException(throwables.getMessage());
        }
        return this.queryAll();
    }

    /**
     * 校验购物车数据
     */
    private DataResponse<OrderVo> ckeckCartData(List<Cart> carts) {
        //数据校验
        for (Cart cart : carts) {
            if (null == cart.getGoodname() || cart.getGoodname().trim().compareTo("")==0){
                return DataResponse.error("商品名称不能为空");
            }
            if (null == cart.getGoodbrand() || cart.getGoodbrand().trim().compareTo("")==0){
                return DataResponse.error("商品品牌不能为空");
            }
            if (null == cart.getQuantity() ){
                return DataResponse.error("商品数量不能为空");
            }
            if (0 >= cart.getQuantity() ){
                return DataResponse.error("商品数量必须大于1");
            }
            if (null == cart.getSaleprice()){
                return DataResponse.error("商品价格不能为空");
            }
            if (0 >= cart.getSaleprice().doubleValue()){
                return DataResponse.error("商品价格不能为0");
            }
            if (null == cart.getInprice() ){
                return DataResponse.error("商品进价不能为空");
            }
            if (null == cart.getType() || cart.getType().trim().compareTo("")==0){
                return DataResponse.error("商品计价单位不能为空");
            }
            if (null == cart.getAgent() || cart.getAgent().trim().compareTo("")==0){
                return DataResponse.error("代办人不能为空");
            }
        }
        return null;
    }

    /**
     * 修改数据
     *
     * @param order 实例对象
     * @return 实例对象
     */
    @Override
    public DataResponse<OrderVo> update(Order order) {
        //健壮性判断
        if (null == order){
            return DataResponse.error("订单不能为空");
        }
        DataResponse<OrderVo> response = checkOrderData(order);
        if (response != null) {
            //日志警告提示
            log.warn("校验失败 -> {}",response.getMsg());
            return response;
        }

        try {
            Order queryById = this.orderDao.queryById(order.getId());
            if (null == queryById){
                //日志警告提示
                log.warn("订单不存在");
                return DataResponse.error("订单不存在");
            }
            int update = this.orderDao.update(order);
            if (update == 0){
                //日志警告提示
                log.warn("更新失败");
                return DataResponse.error("更新失败");
            }
        } catch (SQLException throwables) {
            //日志警告提示
            log.warn("异常 -> {}",throwables.getMessage());
            return DataResponse.errorException(throwables.getMessage());
        }
        return this.queryAll();
    }

    /**
     * 检查订单数据
     */
    private DataResponse<OrderVo> checkOrderData(Order order) {
        if (order.getId() == null){
            return DataResponse.error("不能为空");
        }
        if (order.getProfit() == null){
            return DataResponse.error("不能为空");
        }
        if (order.getTotalPrice() == null){
            return DataResponse.error("不能为空");
        }
        if (order.getOrderNo() == null || order.getOrderNo().trim().compareTo("") == 0){
            return DataResponse.error("不能为空");
        }
        if (order.getDesc() == null || order.getDesc().trim().compareTo("") == 0){
            return DataResponse.error("不能为空");
        }
        if (order.getAgent() == null || order.getAgent().trim().compareTo("") == 0){
            return DataResponse.error("不能为空");
        }
        return null;
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public DataResponse deleteById(Integer id) {
        //健壮性判断
        if (null == id){
            //日志警告提示
            log.warn("ID不能为空");
            return DataResponse.error("ID不能为空");
        }
        try {
            /**
             * 查询订单是否存在
             */
            Order order = this.orderDao.queryById(id);
            if (null == order){
                //日志警告提示
                log.warn("订单不存在");
                return DataResponse.error("订单不存在");
            }
            //删除订单商品
            this.orderItemService.deleteByOrderNo(order.getOrderNo());
            //删除订单
            this.orderDao.deleteById(id) ;
            //删除订单商品
            this.orderDao.deleteByOrderNo(order.getOrderNo());
        } catch (SQLException throwables) {
            //日志警告提示
            log.warn("异常 -> {}",throwables.getMessage());
            return DataResponse.errorException(throwables.getMessage());
        }
        return DataResponse.success("删除成功");
    }
}